package com.tongcao.cn.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.concurrent.Executor;

/**
 * @Author:tongcao
 * @Date:2019/1/3 10:56
 * Description:
 */
@Configuration
@EnableAsync
public class ThreadPoolConfig {

    public static final int POOL_SIZE = 20;

    /**
     * 从异常信息JedisConnectionException: Could not get a resource from the pool来看，我们很容易的可以想到，在应用关闭的        时候异步任务还在执行，由于Redis连接池先销毁了，导致异步任务中要访问Redis的操作就报了上面的错。所以，我们得出结论，上面        的实现方式在应用关闭的时候是不优雅的，那么我们要怎么做呢？
     *
     * @return
     * @link http://blog.didispace.com/springbootasync-3/
     */
    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
        executor.setPoolSize(POOL_SIZE);
        //用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean，这样这些异步任务的销毁就会先于Redis线程池的销毁
        //优雅停机
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("taskExecutor-");
        //该方法用来设置线程池中任务的等待时间，如果超过这个时候还没有销毁就强制销毁，以确保应用最后能够被关闭，而不是阻塞住。
        executor.setAwaitTerminationSeconds(60);
        return executor;
    }

}
